package com.base.test.mutual.utils;

import com.alibaba.fastjson.JSON;
import com.base.commons.tools.exception.BaseOfException;
import com.base.commons.tools.utils.CameTools;
import com.base.commons.tools.utils.HttpConnectUtil;
import com.base.commons.tools.utils.MD5;
import com.base.test.mutual.dto.OwmsReqData;
import com.base.test.mutual.exception.ModuleErrorCode;
import com.base.test.mutual.properties.OwmsProperties;
import com.base.test.mutual.dto.OWMSToken;
import com.base.test.mutual.dto.OwmsGetTokenReqData;
import lombok.extern.log4j.Log4j2;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;

import java.util.*;


/**
 * @author carl
 * @since 2020/1/19
 */
@Log4j2
@Configuration
@EnableConfigurationProperties(OwmsProperties.class)
public class OWMSHttpUtils {
    @Autowired
    private OwmsProperties owmsProperties;
//    @Autowired
//    private TokenRedis tokenRedis;

    /**
     * wms 远程接口
     *
     * @param requestObj 请求参数
     * @param url
     * @param method     方法
     * @param clazz      响应结果的类型
     * @param <T>        响应结果的类型
     * @return
     */
    public <T> T execute(T requestObj, String service, String url, String method, Class<?> clazz) {
        Object obj = null;
        String req = null;
        String sign = null;
        String request = null;
        ResponseEntity res = null;
        OwmsReqData requestParam = new OwmsReqData();
        try {
            //公共请求参数
            requestParam.setRequestId(UUID.randomUUID().toString());
            requestParam.setRequestTime(String.valueOf(System.currentTimeMillis()));
            requestParam.setService(service);
            sign = MD5.MD5Encode(MD5.MD5Encode(owmsProperties.getEncryKey()) + requestParam.getRequestId());
            requestParam.setSign(sign);
            if (null != requestObj) {
                //入参转化下划线
                request = CameTools.toUnderlineJSONString(requestObj);
                requestParam.setRequest(JSON.parseObject(request));

            } else {
                List<String> dataList = Collections.EMPTY_LIST;
                requestParam.setRequest(dataList);
            }
            requestParam.setAppCode(owmsProperties.getAppCode());
            //入参转化下划线
            req = CameTools.toUnderlineJSONString(requestParam);
            log.info("模块Module:{},url:{},请求参数[{}]", "OWMS", url, req);
            res = HttpConnectUtil.tempHttp(req, url, null, method, new HashMap<>(), String.class);
            obj = CameTools.convert(JSON.toJSON(res.getBody()).toString());
            log.info("模块Module:{},url:{},请求结果：{}", "OWMS", url, obj);
        } catch (Exception e) {
            log.error("模块Module:{},url:{},请求参数[{}],请求结果：{}", "OWMS", url, req, res.getBody());
            throw new BaseOfException(ModuleErrorCode.WMS_FAILED, e, "!");
        }
        return (T) obj;
    }

    public <T> T executeAndToken(T requestObj, String serverAddr, String url, String method, Class<?> clazz) {
        url = serverAddr + url;
        HttpHeaders headers = new HttpHeaders();
        OWMSToken jwtToken = generateToken(serverAddr);
        if (jwtToken != null) {
            headers.add(HttpHeaders.AUTHORIZATION, jwtToken.getToken());
        }
        headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
        log.info("模块Module:{},url:{},请求参数{}", "OWMS", url, JSON.toJSONString(requestObj));
        ResponseEntity res = HttpConnectUtil.tempHttp(requestObj, url, headers, method, new HashMap<>(), clazz);
        log.info("模块Module:{},url:{},请求结果：{}", "OWMS", url, res.getBody());
        return (T) res.getBody();
    }

    /**
     * 刷新 owms token
     *
     * @return
     */
    public void refreshOWMSToken(String serverAddr) {
//        String redisKey = RedisKeys.getOwmsTokenKey(owmsProperties.getUserCode() + owmsProperties.getRequestId());
//        OWMSToken token = generateToken(serverAddr);
//        tokenRedis.set(token, redisKey);
    }

    public OWMSToken generateToken(String serverAddr) {
        OwmsGetTokenReqData owmsGetTokenReqData = new OwmsGetTokenReqData();
        owmsGetTokenReqData.setPassword(owmsProperties.getPassword());
        owmsGetTokenReqData.setRequestId(UUID.randomUUID().toString());
        owmsGetTokenReqData.setUserCode(owmsProperties.getUserCode());
        String url = serverAddr + owmsProperties.getRoutesGetToken();
        Map<String, Object> res;
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
            ResponseEntity responseEntity = HttpConnectUtil.tempHttp(owmsGetTokenReqData, url,
                    headers, "post", new HashMap<>(), Map.class);
            res = (Map) responseEntity.getBody();
            log.info("模块Module:{},url:{},请求参数[{}],请求结果：{}", "owms", url, JSON.toJSONString(owmsGetTokenReqData), responseEntity.getBody());
        } catch (Exception e) {
            log.error("模块Module:{},url:{},请求参数[{}],异常信息：{}", "owms", url, JSON.toJSONString(owmsGetTokenReqData), e);
            throw new BaseOfException(ModuleErrorCode.OWMS_FAILED, "同步owms失败,请检查配置是否正确");
        }
        if (!OwmsProperties.SUCCESS_CODE.equals(res.get("code"))) {
            log.error("模块Module:{},url:{},请求参数[{}],异常信息：{}", "owms", url, JSON.toJSONString(owmsGetTokenReqData), "同步owms失败,"+res.get("message"));
            throw new BaseOfException(ModuleErrorCode.OWMS_FAILED, "同步owms失败,"+res.get("message"));
        }
        Map<String, Object> data = (Map<String, Object>) res.get("data");
        OWMSToken owmsToken = new OWMSToken();
        owmsToken.setToken("Bearer" + " " + data.get("token").toString());
        owmsToken.setExpiresIn(DateTime.now().plusSeconds(Integer.parseInt(data.get("expires_in").toString())).toDate());
        return owmsToken;
    }

}
